/**
 * editableText plugin that uses contentEditable property (FF2 is not supported)
 * Project page - http://github.com/valums/editableText
 * Copyright (c) 2009 Andris Valums, http://valums.com
 * Licensed under the MIT license (http://valums.com/mit-license/)
 */
(function(){
   /**
    * The dollar sign could be overwritten globally,
    * but jQuery should always stay accesible
    */
   var $ = jQuery;
   /**
    * Extending jQuery namespace, we
    * could add public methods here
    */
   $.editableText = {};
   $.editableText.defaults = {
      /**
       * 0 : No new lines are enabled
       * 1 : New lines (<br> style) are enabled
       * 2 : A new node (equal to the one in which the event is received)
       *     is created
       */
      newlinesEnabled : 1,
      /**
       * Pass true to enable multiple spaces. For example:
       * "Mutliple[     ]spaces"
       * "Single[ ]space[ ]each[ ]time"
       */
      multipleSpacesEnabled : true,
      /**
       * Event that is triggered when editable text is changed
       */
      changeEvent : 'change'
   };
   /**
    * Usage $('selector).editableText(optionArray);
    * See $.editableText.defaults for valid options 
    */
   $.fn.editableText = function(options){
      var options = $.extend({}, $.editableText.defaults, options);
      
      return this.each(function(){
          // Add jQuery methods to the element
         var editable = $(this);
         
         // --------------------------------------------------------------------
         // Allows user to add a new line, but creating a new child node when he
         // does.
         // --------------------------------------------------------------------
         if (options.newlinesEnabled == 2) {
            editable.keypress(function(event){
               if (event.which == 13) {
                  // If it is an empty node, do not add a new one
                  if (editable.text().length == 0)
                     return event.which != 13;

                  var leave = true;
                  if (editable.caret() == 0)
                     leave = false;

                  var split = editable.splitSelection();
                  newParagraph = $("<p contentEditable=\"true\"></p>");
                  newParagraph.insertAfter(editable);
                  newParagraph.editableText({
                     newlinesEnabled: 2,
                     multipleSpacesEnabled: false });
                  editable.html(split.previousHtml);
                  newParagraph.html(split.nextHtml);
                  if (leave) {
                     editable.blur();
                     newParagraph.focus();
                  }
               }

               // event is cancelled if enter is pressed
               return event.which != 13;
            });
         }

         // --------------------------------------------------------------------
         // New lines without creating a new paragraph (<BR>)
         // --------------------------------------------------------------------
         if (options.newlinesEnabled == 1) {
            editable.keypress(function(event){
               if (event.which == 13) {
                  var split = editable.splitSelection();
                  editable.html(split.previousHtml + "<br>" + split.nextHtml);
               }
               return event.which != 13;
            });
         }

         // --------------------------------------------------------------------
         // Prevents user from adding newlines to headers, links, etc.
         // --------------------------------------------------------------------
         if (options.newlinesEnabled == 0) {
            editable.keypress(function(event){
               // event is cancelled if enter is pressed
               return event.which != 13;
            });
         }

         // --------------------------------------------------------------------
         // Remove an empty paragraph when focus is lost
         // --------------------------------------------------------------------
         editable.blur(function(event){
            if (editable.text() == "") {
               editable.addClass("editableBeingRemoved");
               editable.fadeOut(300, function() { $(this).remove(); });
            }
            else {
               var html = editable.html().replace(/&nbsp;/g, " ");
               html = html.replace(/ \\+/g, " ");
               editable.html(html);
            }
         });

         // --------------------------------------------------------------------
         // Prevents user from adding multiple spaces
         // --------------------------------------------------------------------
         if (!options.multipleSpacesEnabled) {
            editable.keypress(function(event) {
               if (event.which == 32) {
                  var sel = editable.getSelection();

                  var text = editable.text();
                  var cp = editable.caret();

                  if (cp == 0)
                     return false;

                  var cc = text.charAt(cp-1).charCodeAt(0);
                  if (cc == 32 || cc == 160)
                     return false;

                  if (cp < text.length-1) {
                     cc = text.charAt(cp).charCodeAt(0);
                     if (cc == 32 || cc == 160)
                        return false;
                  }
               }

               return true;
            });
         }
      });
   }
})();
